/**
 * Copyright &copy; 2012-2016 <a href="http://www.vc-group.cn">vc-group</a> All rights reserved.
 */
package cn.vcjf.weapp.common.util.weixin;


import cn.vcjf.weapp.common.util.*;
import cn.vcjf.weapp.common.util.httpUtils.HttpClientUtils;
import com.alibaba.fastjson.JSONObject;
import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.LogManager;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.security.PublicKey;
import java.util.HashMap;
import java.util.Map;

/**
 * 信用卡代理商信息（授权登录，信息获取）Service
 * @author liancong
 * @version 2018年6月28日12:14:42
 */
@Service
@Transactional
public class WxWithdrawUtil {
	private static Logger logger = LogManager.getLogger(WxWithdrawUtil.class);
	//从配置文件中获取 mch_appid  mchid
	private static String mch_appid = SysParamUtil.getParam("mch_appid");
	private static String mchKey = SysParamUtil.getParam("mchKey");
	private static String mchid = SysParamUtil.getParam("mchId");
	/**
	 *  提现到微信 零钱
	 * @parm  params  代理商信息
	 */
	public static boolean cashWalletToWeChat(WxWithdrawServer wxWithdrawServer,Map<String,String> params){
		return cashWalletToWeChat(wxWithdrawServer,params, null);
	}
	/**
	 *  提现到微信 零钱
	 * @parm  params  代理商信息
	 */
	public static boolean cashWalletToWeChat(WxWithdrawServer wxWithdrawServer,Map<String,String> params,String cashType){
		boolean flag = true;
		if(StringUtils.isBlank(cashType)){
			cashType = "1";
		}
		//生成cardAgentCash对象参数
		WxWithdrawReq withdrawReq = wxWithdrawServer.buildWxWithdrawReq(params);
		//保存订单表信息
		wxWithdrawServer.saveOrder(params);
		//
		String mchid = SysParamUtil.getParam("mchId");

		//判断提现方式 1、提现到零钱  2、提现到银行卡
		String weChatCashUrl = null;
		String requestXml = null;
		if(cashType.equals("1")){
			//构建提现到零钱xml
			requestXml= cashWalletToWeChatPocket(withdrawReq);
			//微信提现到零钱接口地址
			weChatCashUrl="https://api.mch.weixin.qq.com/mmpaymkttransfers/promotion/transfers";
		}else{
			//构建提现到银行卡xml
			try {
				requestXml = cashWalletToWeChatBankCard(withdrawReq);
			} catch (Exception e) {
				e.printStackTrace();
				//修改钱包表数据
				wxWithdrawServer.doException();
				return  false;
			}
			//微信提现到零钱接口地址
			weChatCashUrl="https://api.mch.weixin.qq.com/mmpaysptrans/pay_bank";
		}
		//正式环境和测试环境 正式地址不一样
		String certPath = SysParamUtil.getParam("certPath");
		WxWithdrawRes wxWithdrawRes = null;
		try {
			//String certPath = "F:/mykey/jar/apiclient_cert.p12";
			String resultXml = HttpClientUtils.httpPostSendReceiveAndCert(weChatCashUrl,requestXml, mchid,certPath);
			logger.info("微信提现返回结果："+resultXml);
			//解析微信提现返回的xml转换成map
			JSONObject json = HttpClientUtils.readStringXml(resultXml);
			wxWithdrawRes = JSONObject.parseObject(json.toJSONString(), WxWithdrawRes.class);
		} catch (Exception e) {
			e.printStackTrace();
		}
		//判断接口调用是否成功提现
		if("SUCCESS".equals(wxWithdrawRes.getResult_code())){
			//修改钱包表数据
			wxWithdrawServer.doSuccess(wxWithdrawRes);
		}else{
			//修改钱包表数据
			wxWithdrawServer.doFailed(wxWithdrawRes);
			flag = false;
		}
		return  flag;

	}



	/**
	 *  构建订单表参数
	 * @parm params 钱包金额信息
	 */
    public static WxWithdrawReq buildWxWithdrawReq(Map<String,String> params){
	    WxWithdrawReq withdrawReq = new WxWithdrawReq();
	    withdrawReq.setOrderNo(params.get("orderNo"));
	    withdrawReq.setBankCardNo(params.get("bankCardNo"));
	    withdrawReq.setBankCode(params.get("bankCode"));
	    withdrawReq.setAmount(params.get("amount"));
	    withdrawReq.setRealName(params.get("realName"));
	    withdrawReq.setOpenid(params.get("openid"));
	    withdrawReq.setDesc(params.get("desc"));
//		withdrawReq.setDesc("分润提现");
		return withdrawReq;
	}


	/**
	 *  构建 提现到微信 零钱 xml
	 * @param cashReq 提现参数对象
	 */
	public static String cashWalletToWeChatPocket(WxWithdrawReq cashReq){
		//获取随机字符串
		String nonce_str = IdGen.getRandomString(8);

		//构建签名参数
		Map<String, String> requestMap = new HashMap<String, String>();
		requestMap.put("mch_appid",mch_appid);
		requestMap.put("mchid",mchid);
		requestMap.put("partner_trade_no", cashReq.getOrderNo());
		requestMap.put("nonce_str",nonce_str);
		String amount = new BigDecimal(cashReq.getAmount()).multiply(new BigDecimal(100)).setScale(0).toString();
		requestMap.put("amount",amount);
		requestMap.put("openid", cashReq.getOpenid());
		requestMap.put("check_name","FORCE_CHECK");
		requestMap.put("re_user_name", cashReq.getRealName());
		requestMap.put("desc",cashReq.getDesc());
		requestMap.put("spbill_create_ip","8.8.8.8");

		//获取签名
		String sign = HttpClientUtils.getSign(requestMap,mchKey).toUpperCase();
		StringBuilder requestXml = new StringBuilder();
		requestXml.append("<xml>");
		requestXml.append("<mch_appid>"+mch_appid+"</mch_appid><mchid>"+mchid+"</mchid>");
		requestXml.append("<partner_trade_no>"+ cashReq.getOrderNo()+"</partner_trade_no>");
		requestXml.append("<nonce_str>"+nonce_str+"</nonce_str>");
		requestXml.append("<openid>"+ cashReq.getOpenid()+"</openid>");
		requestXml.append("<check_name>FORCE_CHECK</check_name>");
		requestXml.append("<re_user_name>"+ cashReq.getRealName()+"</re_user_name>");
		requestXml.append("<amount>"+amount+"</amount>");
		requestXml.append("<desc>"+cashReq.getDesc()+"</desc>");
		requestXml.append("<spbill_create_ip>8.8.8.8</spbill_create_ip>");
		requestXml.append("<sign>"+sign+"</sign>");
		requestXml.append("</xml>");
		return  requestXml.toString();
	}

	/**
	 *  构建 提现到银行卡 xml
	 * @param cashReq 提现参数对象
	 */
	public static String cashWalletToWeChatBankCard(WxWithdrawReq cashReq) throws Exception {
		//获取随机字符串
		String nonce_str = IdGen.getRandomString(8);
		//从配置文件中获取 mch_appid  mchid
		String name64 = getRASBase64(cashReq.getRealName());
		String bankCode64 = getRASBase64(cashReq.getBankCardNo());
		//构建签名参数
		Map<String, String> requestMap = new HashMap<String, String>();
		requestMap.put("mch_id",mchid);
		requestMap.put("partner_trade_no", cashReq.getOrderNo());
		requestMap.put("nonce_str",nonce_str);
		requestMap.put("bank_code", cashReq.getBankCode());
		requestMap.put("enc_bank_no",bankCode64);
		requestMap.put("enc_true_name",name64);
		String amount = new BigDecimal(cashReq.getAmount()).multiply(new BigDecimal(100)).setScale(0).toString();
		requestMap.put("amount",amount);
		requestMap.put("desc", cashReq.getDesc());
		//获取签名
		String sign = HttpClientUtils.getSign(requestMap,mchKey).toUpperCase();
		StringBuilder requestXml = new StringBuilder();
		requestXml.append("<xml>");
		requestXml.append("<mch_id>"+mchid+"</mch_id>");
		requestXml.append("<partner_trade_no>"+ cashReq.getOrderNo()+"</partner_trade_no>");
		requestXml.append("<nonce_str>"+nonce_str+"</nonce_str>");
		requestXml.append("<bank_code>"+ cashReq.getBankCode()+"</bank_code>");
		requestXml.append("<enc_bank_no>"+bankCode64+"</enc_bank_no>");
		requestXml.append("<enc_true_name>"+name64+"</enc_true_name>");
		requestXml.append("<amount>"+amount+"</amount>");
		requestXml.append("<desc>"+cashReq.getDesc()+"</desc>");
		requestXml.append("<sign>"+sign+"</sign>");
		requestXml.append("</xml>");
		return  requestXml.toString();

	}

	/**
	 *  通过微信的public.pem 进行加密
	 * @param str 需加密字符串
	 *
	 */
	public static String getRASBase64(String str) throws Exception {
		String publicPath = SysParamUtil.getParam("publicPath");
		//String publicPath = "F:/mykey/jar/public.pem";
		PublicKey pub=RASUtils.getPubKey(publicPath,"RSA");
		String rsa ="RSA/ECB/OAEPWITHSHA-1ANDMGF1PADDING";
		//进行加密
		byte[] estr = RASUtils.encrypt(str.getBytes(),pub,2048, 11,rsa);
		return Encodes.encodeBase64(estr);
	}

}